|
CallGraph
|
00001 #include "dotwriter.h" 00002 #include <wx/strconv.h> 00003 #include <wx/file.h> 00004 #include <wx/msgdlg.h> 00005 #include <wx/math.h> 00006 #include <math.h> 00007 00008 00009 DotWriter::DotWriter() 00010 { 00011 begin_graph = wxT("digraph\n{"); 00012 end_graph = wxT("}\n"); 00013 fontname = wxT("Arial"); 00014 style = wxT("filled"); 00015 shape = wxT("box"); 00016 cwhite = wxT("white"); 00017 cblack = wxT("black"); 00018 hnode = wxT(""); 00019 dedge = wxT(""); 00020 hedge = wxT(""); 00021 dlabel = wxT(""); 00022 graph = wxT(""); 00023 output = wxT(""); 00024 mlines = NULL; 00025 m_mgr = NULL; 00026 dwcn = 0; 00027 dwce = 0; 00028 dwtn = 0; 00029 dwte = 0; 00030 dwbname = false; 00031 dwbparam = false; 00032 writedotfile = false; 00033 } 00034 00035 DotWriter::~DotWriter() 00036 { 00037 00038 } 00039 00040 void DotWriter::setLineParser(LineParserList *pLines )//, int numOfLines) 00041 { 00042 mlines = pLines; 00043 } 00044 00045 void DotWriter::setDotWriterFromDialogSettings(IManager *mgr) 00046 { 00047 m_mgr = mgr; 00048 m_mgr->GetConfigTool()->ReadObject(wxT("CallGraph"), &confData); 00049 dwcn = confData.GetColorsNode(); 00050 dwce = confData.GetColorsEdge(); 00051 dwtn = confData.GetTresholdNode(); 00052 dwte = confData.GetTresholdEdge(); 00053 dwbname = confData.GetBoxName(); 00054 dwbparam = confData.GetBoxParam(); 00055 } 00056 00057 00058 void DotWriter::WriteToDotLanguade() 00059 { 00060 int pl_index = 0; 00061 float pl_time = 0; 00062 bool is_node = false; 00063 wxArrayInt index_pl_nodes; 00064 00065 if (mlines == NULL) 00066 return; 00067 00068 graph = wxT("graph [ranksep=\"0.25\", fontname=") + fontname + wxT(", nodesep=\"0.125\"];"); 00069 00070 hnode = wxT("node [label=\"\\N\", fontname=") + fontname + wxT(", style=") + style + wxT(", height=0, width=0, shape=") + shape + wxT(", fontcolor=") + cwhite + wxT("];"); 00071 00072 hedge = wxT("edge [fontname=") + fontname + wxT("];"); 00073 00074 //graph []; -- not used 00075 00076 output += begin_graph + wxT("\n") + graph + wxT("\n") + hnode + wxT("\n") + hedge + wxT("\n"); 00077 00078 LineParserList::compatibility_iterator it = mlines->GetFirst(); 00079 00080 while(it) 00081 { 00082 LineParser *line = it->GetData(); 00083 00084 //if (line->name.IsEmpty()) break; 00085 00086 if(line->pline && wxRound(line->time) >= dwtn) 00087 { 00088 is_node = true; 00089 index_pl_nodes.Add(line->index); 00090 dlabel = wxString::Format(wxT("%i"),line->index); 00091 dlabel += wxT(" [label=\""); 00092 dlabel += OptionsShortNameAndParameters(line->name); 00093 dlabel += wxT("\\n"); 00094 dlabel += wxString::Format(wxT("%.2f"), line->time); 00095 dlabel += wxT("% \\n"); 00096 dlabel += wxT("("); 00097 dlabel += wxString::Format(wxT("%.2f"), line->self); 00098 dlabel += wxT("%)"); 00099 dlabel += wxT("\\n"); 00100 if(line->called0 != -1) 00101 dlabel += wxString::Format(wxT("%i"),line->called0) + wxT("x"); 00102 //if(line->recursive) 00103 // dlabel += wxT(" (") + wxString::Format(wxT("%i"),line->called0 + line->called1) + wxT("x)"); 00104 dlabel += wxT("\",fontcolor=\""); 00105 dlabel += DefineColorForLabel(ReturnIndexForColor(line->time, dwcn)); 00106 dlabel += wxT("\", color=\""); 00107 dlabel += DefineColorForNodeEdge(ReturnIndexForColor(line->time, dwcn)); 00108 // 00109 dlabel += wxT("\", fontsize=\"12.00\"];"); 00110 // 00111 output += dlabel + wxT("\n"); 00112 // 00113 dlabel.Clear(); 00114 } 00115 it = it->GetNext(); 00116 } 00117 00118 it = mlines->GetFirst(); 00119 00120 while(it) 00121 { 00122 LineParser *line = it->GetData(); 00123 00124 if(line->pline) 00125 { 00126 pl_index = line->index; // index for primary node 00127 pl_time = line->time; // time for primary node 00128 } 00129 00130 if (line->child && IsInArray(line->nameid,index_pl_nodes) && IsInArray(pl_index,index_pl_nodes) && (wxRound(pl_time) >= dwte)) 00131 { 00132 dedge = wxString::Format(wxT("%i"), pl_index); 00133 dedge += wxT(" -> "); 00134 dedge += wxString::Format(wxT("%i"),line->nameid); 00135 dedge += wxT(" [color=\""); 00136 dedge += DefineColorForNodeEdge(ReturnIndexForColor(pl_time, dwce)); // color by primary node 00137 dedge += wxT("\", label=\""); 00138 //if(line->self != -1) 00139 //dedge += wxString::Format(wxT("%.2f"),line->self) + wxT("%"); 00140 //dedge += wxT("\\n"); 00141 dedge += wxString::Format(wxT("%i"),line->called0); 00142 dedge += wxT("x"); 00143 dedge += wxT("\" ,arrowsize=\"0.50\", fontsize=\"10.00\", fontcolor=\""); 00144 dedge += cblack; 00145 dedge += wxT("\", penwidth=\"2.00\"];"); // labeldistance=\"4.00\", 00146 // 00147 output += dedge + wxT("\n"); 00148 // 00149 dedge.Clear(); 00150 } 00151 it = it->GetNext(); 00152 } 00153 output += end_graph; 00154 00155 if (!is_node) // if the call graph is empty create new graph with label node 00156 { 00157 output = wxT("digraph e {0 [label="); 00158 output += wxT("\"Call Graph is empty, please check settings of node resolutions for this plugin!\""); 00159 output += wxT(", shape=none, height=2, width=2, fontname=Arial, fontsize=14.00];}"); 00160 } 00161 } 00162 00163 void DotWriter::SendToDotAppOutputDirectory(wxString apppathfolder) 00164 { 00165 wxString dotfilespath = apppathfolder + stvariables::dotfilesdir + stvariables::sd; 00166 wxString dottxtpath = dotfilespath + stvariables::dottxtname; 00167 if(!wxDirExists(dotfilespath)) 00168 { 00169 wxMkdir(dotfilespath.c_str()); 00170 } 00171 00172 if (wxFileExists(dottxtpath)) 00173 wxRemoveFile(dottxtpath); 00174 00175 //create new txt file 00176 wxFile pFile(dottxtpath, wxFile::write); 00177 pFile.Open(dottxtpath, wxFile::write); 00178 00179 if(pFile.IsOpened()) 00180 { 00181 writedotfile = pFile.Write(output); 00182 pFile.Close(); 00183 } 00184 else 00185 { 00186 return; 00187 } 00188 } 00189 00190 bool DotWriter::DotFileExist(wxString apppathfolder) 00191 { 00192 wxString dotfilespath = apppathfolder + stvariables::dotfilesdir + stvariables::sd + stvariables::dottxtname; 00193 00194 if (wxFileExists(dotfilespath) && writedotfile) 00195 return true; 00196 else return false; 00197 } 00198 00199 wxString DotWriter::OptionsShortNameAndParameters(wxString name) 00200 { 00201 if (name.Contains(wxT('(')) && name.Contains(wxT(')')) && dwbname) 00202 { 00203 wxString out = name.BeforeFirst(wxT('(')); 00204 out += wxT("()"); // for function return just () 00205 return out; 00206 00207 } 00208 else if (name.Contains(wxT('(')) && name.Contains(wxT(')')) && dwbparam) 00209 { 00210 wxString out = name.BeforeFirst(wxT('(')); 00211 wxString sub = name.AfterFirst(wxT('(')).BeforeFirst(wxT(')')); 00212 if (sub.IsEmpty()) 00213 { 00214 out += wxT("\\n(\\n)"); 00215 return out; 00216 } 00217 else if(sub.Contains(wxT(","))) 00218 { 00219 sub.Replace(wxT(","), wxT(",\\n")); 00220 out += wxT("\\n(\\n") + sub + wxT("\\n)"); 00221 return out; 00222 } 00223 else 00224 { 00225 out += wxT("\\n(\\n") + sub + wxT("\\n)"); 00226 return out; 00227 00228 } 00229 } 00230 else return name; 00231 } 00232 00233 int DotWriter::ReturnIndexForColor(float time, int dwc) 00234 { 00235 int index = 0; 00236 struct BarvaRozsah 00237 { 00238 int dolniIndex; 00239 int horniIndex; 00240 int indexBarvy; 00241 }; 00242 00243 BarvaRozsah *barvyVybrane; 00244 barvyVybrane = new BarvaRozsah[dwc]; 00245 00246 if(dwc == 1) 00247 { 00248 barvyVybrane[0].dolniIndex = 0; 00249 barvyVybrane[0].horniIndex = 100; 00250 barvyVybrane[0].indexBarvy = 0; 00251 } 00252 else if(dwc == 2) 00253 { 00254 barvyVybrane[0].dolniIndex = 0; 00255 barvyVybrane[0].horniIndex = 50; 00256 barvyVybrane[0].indexBarvy = 0; 00257 barvyVybrane[1].dolniIndex = 51; 00258 barvyVybrane[1].horniIndex = 100; 00259 barvyVybrane[1].indexBarvy = 9; 00260 } 00261 else if(dwc > 2 && dwc < 11) 00262 { 00263 int pocetIntervalu = dwc-1; 00264 float krokIntervalu = 8.0/(float)pocetIntervalu; 00265 float delkaIntervalu = 100.0/(float)dwc; 00266 delkaIntervalu = round(delkaIntervalu); 00267 int poModulu = 8 % pocetIntervalu; 00268 float zbytekPripocet = (float)poModulu/pocetIntervalu; 00269 float pripocitat = 0.0; 00270 00271 for(int i=0; i<dwc; i++) 00272 { 00273 pripocitat += zbytekPripocet; 00274 if(i==0) 00275 { 00276 barvyVybrane[i].dolniIndex = 0; 00277 barvyVybrane[i].horniIndex = (int)delkaIntervalu; 00278 barvyVybrane[i].indexBarvy = 0; 00279 } 00280 else if(i==(dwc-1)) 00281 { 00282 barvyVybrane[i].dolniIndex = barvyVybrane[i-1].horniIndex+1; 00283 barvyVybrane[i].horniIndex = 100; 00284 barvyVybrane[i].indexBarvy = 9; 00285 } 00286 else if(i>0 && i<(dwc-1)) 00287 { 00288 int pripocet = 0; 00289 if(0.8 < pripocitat && pripocitat < 1.2) 00290 { 00291 pripocet = 1; 00292 pripocitat = 0; 00293 } 00294 barvyVybrane[i].dolniIndex = barvyVybrane[i-1].horniIndex + 1; 00295 barvyVybrane[i].horniIndex = barvyVybrane[i-1].horniIndex + (int)delkaIntervalu; 00296 barvyVybrane[i].indexBarvy = (int)round((float)barvyVybrane[i-1].indexBarvy + krokIntervalu) + pripocet; 00297 } 00298 } 00299 } 00300 00301 for(int i=0; i<dwc; i++) 00302 { 00303 if ((int)barvyVybrane[i].dolniIndex <= (int)time && (int)time <= (int)barvyVybrane[i].horniIndex) 00304 { 00305 index = (int)barvyVybrane[i].indexBarvy; 00306 break; 00307 } 00308 } 00309 return index; 00310 } 00311 00312 wxString DotWriter::DefineColorForNodeEdge(int index) 00313 { 00314 wxString colors[10] = {wxT("#006837"), wxT("#1a9850"), wxT("#66bd63"), wxT("#a6d96a"), wxT("#d9ef8b"), wxT("#fee08b"), wxT("#fdae61"), wxT("#f46d43"), wxT("#d73027") ,wxT("#a50026")}; 00315 return colors[index]; 00316 } 00317 00318 bool DotWriter::IsInArray(int index, wxArrayInt arr) 00319 { 00320 for(unsigned int i = 0; i < arr.GetCount(); i++) 00321 { 00322 if (arr.Item(i) == index) return true; 00323 } 00324 return false; 00325 00326 } 00327 00328 wxString DotWriter::DefineColorForLabel(int index) 00329 { 00330 if ((index < 3) || (index > 6)) 00331 { 00332 return cwhite; 00333 } 00334 else 00335 { 00336 return cblack; 00337 } 00338 }